<?php

namespace catchAdmin\login\controller;

use app\common\lib\Redis;
use app\impl\SyncDiagnosis;
use app\impl\SyncInHospital;
use app\impl\SyncInHospitalOps;
use app\impl\SyncOutHospital;
use app\impl\SyncOutpatientClinic;
use app\impl\syncPatientInfo;
use app\Request;
use catchAdmin\login\request\CaptcherRequest;
use catchAdmin\login\request\LoginRequest;
use catchAdmin\permissions\model\Users;
use catcher\base\CatchController;
use catcher\base\CatchRequest;
use catcher\CatchAuth;
use catcher\CatchResponse;
use catcher\Code;
use catcher\exceptions\LoginFailedException;
use catcher\exceptions\ValidateFailedException;
use edward\captcha\Captcha;
use edward\captcha\facade\CaptchaApi;
use thans\jwt\facade\JWTAuth;

class Index extends CatchController
{
    /**
     * 登陆
     *
     * @time 2019年11月28日
     * @param LoginRequest $request
     * @param CatchAuth $auth
     * @return \think\response\Json
     */
    public function login(LoginRequest $request, CatchAuth $auth)
    {

        $captcha = $request->param("captcha");
        $hashCode = $request->param("hash_code");

        if (CaptchaApi::check($captcha, $hashCode) === false) {
            throw new ValidateFailedException("验证码错误");
        }
        $condition = $request->param();
        $condition["doctor_code"] = $condition["email"];
        try {
            $token = $auth->attempt($condition);
            $user = $auth->user();
            $userKey = hash("sha256", $user["id"] . "_" . $_SERVER["REMOTE_ADDR"] . '_' . $_SERVER["HTTP_USER_AGENT"]);
            Redis::getInstance()->redis->setex($userKey, 3600, $token);
            Redis::getInstance()->redis->setex("jwt:user:" . $user["id"], 86400, $token);
            $this->afterLoginSuccess($user, $token);
            // 登录事件
            $this->loginEvent($user->username);
            # 判断是否存在错误数，如果存在清空
            if (Redis::getInstance()->redis->exists("user:login:" . $user->id)) {
                Redis::getInstance()->redis->del("user:login:" . $user->id);
            }
            return CatchResponse::success([
                'token' => $token,
            ], '登录成功');
        } catch (ValidateFailedException $validateFailedException) {
            return CatchResponse::fail($validateFailedException->getMessage(), Code::LOGIN_FAILED);
        } catch (\Exception $exception) {

            $this->detailWithLoginFailed($exception, $condition);
            $code = $exception->getCode();

            return CatchResponse::fail($code == Code::USER_FORBIDDEN ?
                '该账户已被禁用，请联系管理员' : '登录失败,请检查邮箱和密码', Code::LOGIN_FAILED);
        }
    }

    public function getCaptcha(CaptcherRequest $request, CatchAuth $auth): \think\response\Json
    {
        $data = CaptchaApi::create();

        return CatchResponse::success(["captcha_code" => urlencode($data['base64']), 'hash_code' => $data['key']]);

    }

    /**
     * 处理登录失败
     *
     * @time 2020年10月26日
     * @param $exception
     * @param $condition
     * @return void
     */
    protected function detailWithLoginFailed($exception, $condition)
    {
        $message = $exception->getMessage();

        if (strpos($message, '|') !== false) {
            $username = explode('|', $message)[1];
        } else {
            $username = $condition['email'];
        }

        $this->loginEvent($username, false);
    }

    /**
     * 用户登录成功后
     *
     * @time 2020年09月09日
     * @param $user
     * @param $token
     * @return void
     */
    protected function afterLoginSuccess($user, $token)
    {
        $user->last_login_ip = request()->ip();
        $user->last_login_time = time();
        if ($user->hasField('remember_token')) {
            $user->remember_token = $token;
        }
        $user->save();
    }

    /**
     * 登录事件
     *
     * @time 2020年09月09日
     * @param $name
     * @param bool $success
     * @return void
     */
    protected function loginEvent($name, $success = true)
    {
        $params['login_name'] = $name;
        $params['success'] = $success ? 1 : 2;
        event('loginLog', $params);
    }


    /**
     * 登出
     *
     * @time 2019年11月28日
     * @return \think\response\Json
     */
    public function logout(): \think\response\Json
    {
        return CatchResponse::success();
    }

    /**
     * refresh token
     *
     * @return \think\response\Json
     * @author JaguarJack
     * @email njphper@gmail.com
     * @time 2020/5/18
     */
    public function refreshToken()
    {
        return CatchResponse::success([
            'token' => JWTAuth::refresh()
        ]);
    }

    public function test()
    {
        (new SyncOutHospital())->run(["type" => "2"]);
    }
}
